module Main where

import Data
import InputParser
import Validator
import Reducer
import OutputProcessing
import System(getArgs)

main :: IO ()
main = do
  args <- getArgs
  if length args < 2
    then usage
    else do
      startpoint <- readStartpoint (last args)
      let fnames = take (length args - 1) args
      modules <- readModules fnames
      let grammar = transform startpoint modules
      let output  = createOutput grammar
      putStr output

usage :: IO ()
usage = putStrLn "Usage: fika <module1> [<module2> .. <moduleN>] baseModule.initNT"

transform :: StartPoint -> [Module] -> Grammar
transform startpoint modules =
  if validateModules modules && validateOutput output
    then output
    else error msg
  where
    output = reduce startpoint modules
    msg = "Error while processing input data."


readStartpoint :: String -> IO StartPoint
readStartpoint cmdlinearg =
    case (parseStartpoint cmdlinearg) of
      Left err -> do
                    putStr "parse error at "
                    print err
                    usage
                    error "Invalid syntax at initNT.BaseModule"
      Right out -> return out

readModules :: [Filename] -> IO [Module]
readModules [] = return []
readModules (fname:rest) =
  do
    modules <- readModulesFromFile fname
    restModules <- readModules rest
    let allModules = modules ++ restModules
    return allModules

readModulesFromFile :: Filename -> IO [Module]
readModulesFromFile fname =
  do
    content <- readFile fname
    case (parseInput fname content) of
                 Left err -> do
                               putStr "parse error at "
                               print err
                               error "Error while loading input data."
                 Right out -> return out

-- EOF
